AngularJs 学习笔记(三)

个人笔记整理,有误欢迎指正

作者 Mr.Woo 日期 2016-12-04
AngularJs 学习笔记(三)

AngularJs 学习笔记(三)


一、作用域

  • 先找自己,再找父级
  • 子级可以访问父级的元素
  • 父级不能访问子级的元素。如果在该作用域下元素没有值,则该值为空不显示
  • 每个控制器又都对应一个模型,也就是$scope对象,不同层级控制器下的$scope便产生了作用域

    <script>
     var app = angular.module('app',[]);
     通过ng-controller指令可以创建一个子作用域,
     新建的作用域可以访问父作用域的数据
     app.controller('wooController1',['$scope',function ($scope) {
         $scope.name = "woo1";
     }]);
     app.controller('wooController2',['$scope',function ($scope) {
         $scope.name = "woo2";
     }])
    </script>
    

ng-init初始化全局变量

  • 一个AngularJs的应用,在启动时会自动创建一个根作用域$rootScope,这个根作用域在整个应用范围(ng-app所在标签以内)都是可以被访问到的
  • 使用ng-init=“属性名称=属性值”
  • 使用ng-init创建的就是根作用域

    <body ng-app="app" ng-init="name='init'">
    <div ng-controller="wooController2">
         <p>----{{name}}</p>
         <ul ng-controller="wooController1">
             <li>{{name}}</li>
         </ul>
    </div>
    

二、过滤器

过滤器是用来了格式化数据用的

angular内置了9个过滤器

  1. currency:将数值格式化为货币格式
  2. date:日期格式化,年(y)、月(M)、日(d)、星期(EEEE/EEE)、时(H/h)、分(m)、秒(s)、毫秒(.sss),也可以组合到一起使用。
  3. filter:在给定数组中选择满足条件的一个子集,并返回一个新的数组,其条件可以是一个字符串、对象、函数
  4. josn:将javascript对象转成JSON字符串
  5. limitTo:取出字符串或数组的前(正数)几位或后(负数)几位
  6. lowercase:将文本转换成小写格式
  7. uppercase:将文本转换成大写格式
  8. number:数字格式化,可控制小位位数
  9. orderBy:对数组进行排序,第2个参数可控制方向
app.controller('wooController',['$scope',function ($scope) {

     $scope.price = 20;
     $scope.nowDate = new Date();
     $scope.course = ['html','js','css'];
     $scope.student = [{name:'zs',age:18},{name:'ls',age:20},
    {name:'ww',age:10}];
     $scope.str = 'hello world';
     $scope.num = "10";
}])
<body ng-app="app" ng-controller="xmgController">
     管道符 上次的结果当作下一次的参数进行传递
     过滤器的本质是一个方法
     会自动把|前面的内容,当作方法的第一个参数传入
     如果想要自己手动传参 使用:来进行传递

<p>{{price|currency:'&'}}</p>
<p>{{nowDate|date:'yyyy/MM/dd h:m:s'}}</p>
<p>{{course|filter:'s'}}</p>
<p>{{student|json}}</p>
<p>{{student|limitTo:-2}}</p>
<p>{{str|uppercase|lowercase}}</p>
<p>{{student|orderBy:'age':false}}</p> true 是降序 false是升序
<p>{{num|number:2}}</p> 在num当中不能出现非数字

自定义过滤器

AngularJs内置过滤器外,还可以根据业务需要自定义过滤器

通过模块对象实例提供的filter方法自定义过滤器

<script>
 var app = angular.module('app',[]);
 自定义控制器
 app.controller('wooController',['$scope',function ($scope) {
     $scope.name = "121";
     $scope.str = "hello";
 }]);

 自定义指令
 app.directive('directiveName',[function () {
     return {
     };
 }]);

 自定义过滤器
 第一个参数:过滤器的名称
 第二个参数:回调函数
 返回值为一个函数(input 为自动传入的数据,它为管道符前面的内容)
 app.filter('filterName',[function () {
     return function (input) {
          console.log('hello'+ input);
     }
 }]);

 app.filter('firstUppcase',[function () {
     return function (input) {
         slice:从指定的位置,截取到末尾
         return input[0].toUpperCase()+input.slice(1)
     };
 }]);
</script>

<body ng-app="app" ng-controller="wooController">
<p>{{name|filterName}}</p>
<p>{{str|firstUppcase}}</p>
</body>

三、依赖注入

  • AngularJs采用模块化的方式组织代码,将一些通用逻辑封装成一个对象或函数,实现最大程度的复用
  • 这导致了使用者和被使用者之间存在依赖关系
  • 所谓依赖注入是指在运行时自动查找依赖关系
  • 然后将查找到依赖传递给使用者的一种机制

依赖注入分为两种:

1.行内式注入

以数组形式明确声明依赖,数组元素都是包含依赖名称的字符串,数组最后一个元素是依赖注入的目标函数

推荐使用行内式注入

2.推断式注入

没有明确声明依赖,AngularJs会将函数参数名称当成是依赖的名称

这种方式会带来一个问题,当代码经过压缩后函数的参数被压缩,这样便会造成依赖无法找到

<script>
 var app = angular.module('app',[]);
 自定义控制器
 1.行内式注入
 app.controller('wooController',
['$scope','$http',function ($scope,$http) {
     $scope.name = "121";
     $scope.str = "hello";
 }]);

 2.推断式注入
 app.controller('wooController',function ($scope,$http) {
     $scope.name = 'woo';
 });
</script>

四、服务

服务是一个对象或函数,对外提供特定的功能

常见内置服务有:

  • $location
  • $timeout
  • $filter
  • $log
  • $http

  • 同时还支持多种快捷方式如$http.get()、$http.post()、$http.json

$location服务

  1. $location服务解析在浏览器地址栏中的URL(基于window.location)并且让URL在你的应用中可用。
  2. $localtion.ablUrl() 获取绝对路径
  3. $localtion.protocol() 获取协议
  4. $localtion.port() 端口
  5. $localtion.path() 当前路径
  6. $localtion.hash 获取hash值
  7. $localtion.search 查询字符串
网络地址
* http:// 协议
* localhost:主机地址 www.baidu.com 139.129.256.5
* :8080 端口号
 * /code/06-$location服务.html 文件路径
 * # 锚点
* ?name=xmg&&age=10 传的参数

可以查看原生的网络地址
for ( var key in location) {
 console.log(key +'=>'+location[key]);
}



var app = angular.module('app',[]);
app.controller('wooController',
['$scope','$location',function ($scope,$location) {
     $scope.absUrl = $location.absUrl();
     获取的是锚点后面的地址
     $scope.url = $location.url();
     端口号
     $scope.port = $location.port();
     主机名
     $scope.host = $location.host();
     获取的锚点。从第二个锚点开始的值
     $scope.hash = $location.hash();
     参数
     $scope.search = $location.search();
}]);

 <p>{{absUrl}}</p>
 <p>{{url}}</p>
 <p>{{port}}</p>
 <p>{{host}}</p>
 <p>{{hash}}</p>
 <p>{{search}}</p>

$timeout和$interval服务

$timeout&$interval对原生Javascript中的setTimeout和setInterval进行了封装。

var app = angular.module('app',[]);

app.controller('wooController',
['$scope','$timeout','$interval',function ($scope,$timeout,$interva
l) {
         $scope.name = 'woo';
        延时执行任务
        $timeout(function () {
            $scope.name="xmg123";
         },1000);

         隔指定时间执行任务
         var timer = $interval(function () {
             $scope.dateTime = new Date();
         },1000);

         点击按钮停止定时器
         $scope.stop = function () {
             alert('aaa');
             停止指定的定时器
              $interval.cancel(timer);
         }
 }]);

<p>{{name}}</p>
<p>{{dateTime | date:'yyyy-MM-dd h:m:s'}}</p>
<button ng-click="stop()">停止</button>

$filter服务

  • 行内式注入
  • 不要在view中过多的处理业务逻辑,应该在控制器当中处理完毕后,直接显示到view
app.controller('wooController',
['$scope','$filter',function ($scope,$filter) {
     $scope.price = 20;
     $scope.str = "hello";

     使用$filter获取9个服务中的一个
     获取后再去使用获取的筛选
     var currency = $filter('currency');
     $scope.price = currency($scope.price);

     var uppcase = $filter('uppercase');
     $scope.str = uppcase($scope.str);

     可以直接在后面使用
     $scope.str = $filter('limitTo')($scope.str,2);
}]);

$log服务

var app = angular.module('app',[]);
app.controller('wooController',['$log',function ($log) {
     $log.log('woo');
     $log.info('woo');
     $log.warn('woo');
     $log.error('woo');
     $log.debug('woo');
}]);

$http服务

var app = angular.module('app',[]);
 app.controller('wooController',
['$scope','$http',function ($scope,$http) {
     $http({
         url: 'get.php', 请求地址
         method:'get', 请求方法
        params:{ get方式传递参数 在传递过程中,会自动帮你转成
                 get.php?name=woo

               传递时->name:woo
               name:'woo'
              }
     }).success(function (res) {  注意:这里的success和error是在angular1.5之前的,1.6是用then跟catch
          alert(res); 成功时回调
     }).error(function(error){
          失败时回调
     });

     $http({
          url: 'post.php', 请求地址
          method:'post',   请求方法
         post必须得要设置请求头
         headers:{
         'Content-Type':'application/x-www-formurlencoded'
         },

          //data:{ data:{} 传参形式 在传递数据时,是以json来传递的
             name:"woo" json串
          }

          data:'name=woo'  formdata
     }).success(function (res) {
         alert(res);
     }).error(function (res) {

     });

     当设置请求头的时候为application/x-www-form-urlencoded是以soap 以对象形式传递

         SOAP: 以对象形式传递
         RESTFUL:json串形式进行传递
     }]);

自定义服务分为三种:

1.factory

app.factory('show',function () {
 return function () { 直接以方法来调用
   alert("hello");
 };
 function show1() {
     alert("show1");
    逻辑
 }
 function show2() {
     alert("show2");
 }
 return {
     show1:show1,
     show2:show2
 }
});


自定义控制器
使用自己定义的服务要注入进来
app.controller('wooController',
['$scope','$http','show',function ($scope,$http,show) {
 show.show1();
 show.show2();
}]);

2.service

如果要依赖其他的服务,那么就把其他的服务注入进来
 app.service('showTime',['$filter',function ($filter) {
    里面所有的功能要使用this来定义
     this.cur_date = function () {
         var cur_date = new Date();
         var date = $filter('date');
         return date(cur_date,'yyyy-MM-dd h:m:s');
     };
     this.sayHello = function () {
     alert("hello world");
     }
 }]);

 service自定义服务,所有的方法都是以this的方式定义
 var app = angular.module('app',[]);

 同样也是要注入自定义的服务
 app.controller('wooController',
['$scope','showTime',function ($scope,showTime) {
     $scope.cur_date = showTime.cur_date();

     调用服务
     showTime.sayHello();
 }]);

<body ng-app="app" ng-controller="wooController">
<h1>{{cur_date}}</h1>

3.value

  • value表现形式上是一个服务
  • 本质上可看做是一个常量
  • 常量:其值始终保持不变的量
  • 变量:其值可以发生改变的量

    var app = angular.module('app',[]);
    注入服务
    app.controller('wooController',
    ['$scope','key','version',function ($scope,key,version) {
         $scope.key = key;
         $scope.version = version;
    }]);
    使用服务
    app.value('version','1.0’);
    app.value('key','woo');
    

五、跨域原理

1.什么是跨域?

不同域名之间进行数据的访问

2.使用jsonp

Ajax与jsonp有关系吗

jsonp与ajax是没有关系的。ajax是使用js内置的对象进行网络请求获取数据,是一种技术。jsonp是使用script当中的src来获取数据

为什么会有跨域?

为了数据的安全

是谁导致了跨域?

是浏览器。
浏览器为了保证数据的安全,不允许直接使用别的域名数据。浏览器做了一个拦截。其实数据已经响应到了浏览器。浏览器没有把它给我们

解决跨域方式:

使用script当中src方式进行数据请求

  1. 在前端定义一个function

    function fn(res) {
     alert(res);
     }
    
  2. 通过创建一个<script src=>向服务器发送一个请求。src当中去请求要跨域的网络地址,src的地址当中要添加一个参数callback,并且值就是声明的方法名称
    <script src="get.php?callback=fn"></script>

  3. 服务器接受callback值
    $fn = $_GET['callback']

  4. 在返回时,在接收参数这后面拼接一个括号。如果想要传递数据,就把数据放到括号当中。echo $fn.'("xmg123")';

  5. 就会执行前端定义的function fn("hello");

跨域只有前端处理,是没有办法达到效果的。必须得要结合后端一起,来去处理

使用Angular $http实现跨域

$http({
    url:'',
    method:'jsonp',
    params:{

        pin:'',
        uuid: -1,
        callback:'JSON_CALLBACK' 
        //当为jsonp时,会自动帮你添加一个script
        //帮你生成一个方法(angular.callbacks._0)
    }
})

使用php做桥接实现跨域

echo file_get_contents('https://xxxxxxx')